// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Test throwing exceptions from an imported function.

import "package:expect/expect.dart";
import "dart:wasm";
import "dart:typed_data";

void main() {
  // int64_t fn(int64_t x) { return throwIfNegative(x); }
  var data = Uint8List.fromList([
    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
    0x01, 0x7e, 0x01, 0x7e, 0x02, 0x17, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0f,
    0x74, 0x68, 0x72, 0x6f, 0x77, 0x49, 0x66, 0x4e, 0x65, 0x67, 0x61, 0x74,
    0x69, 0x76, 0x65, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01,
    0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01,
    0x7f, 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x0f, 0x02, 0x06, 0x6d,
    0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x66, 0x6e, 0x00, 0x01,
    0x0a, 0x0c, 0x01, 0x0a, 0x00, 0x20, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80,
    0x00, 0x0b,
  ]);

  dynamic override = null;
  var inst = WasmModule(data).instantiate(WasmImports()
    ..addMemory("env", "memory", WasmMemory(256, 1024))
    ..addGlobal<Int32>("env", "__memory_base", 1024, false)
    ..addFunction<Int64 Function(Int64)>("env", "throwIfNegative", (int x) {
      if (x < 0) {
        throw Exception(x);
      }
      if (override != null) {
        return override;
      }
      return x;
    }));
  var fn = inst.lookupFunction<Int64 Function(Int64)>("fn");

  Expect.equals(123, fn.call([123]));
  Expect.throws(() => fn.call([-456]), (Exception e) => "$e".contains("-456"));

  override = "Not an integer";
  Expect.throwsArgumentError(() => fn.call([789]));
  override = 0.123;
  Expect.throwsArgumentError(() => fn.call([789]));
}
